#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <direct.h>


#define CONTROL_PORT 21
#define DATA_PORT 20
#define BUFFER_SIZE 1024

SOCKET data_sock = INVALID_SOCKET;
SOCKET data_client = INVALID_SOCKET;
int passive_mode = 0;  // 0-off, 1-on

void send_response(SOCKET client, const char* response) {
    send(client, response, strlen(response), 0);
    printf("S: %s", response);
}

void handle_pasv(SOCKET client) {
    // 简化实现：使用固定端口 2024
    send_response(client, "227 Entering Passive Mode (127,0,0,1,7,232)\r\n");
    passive_mode = 1;
}

void handle_list(SOCKET client) {
    if (passive_mode) {
        data_client = accept(data_sock, NULL, NULL);
        send_response(client, "150 Opening data connection\r\n");
        
        // 发送目录列表（简化版）
        const char* list = "drwxr-xr-x 2 user group 4096 Dec 12 testdir\r\n";
        send(data_client, list, strlen(list), 0);
        
        closesocket(data_client);
        send_response(client, "226 Transfer complete\r\n");
    }
    else {
        send_response(client, "425 Use PASV first\r\n");
    }
}

void handle_retr(SOCKET client, char* filename) {
    // 文件传输实现
    send_response(client, "150 Opening BINARY mode data connection\r\n");
    // [实际文件传输代码]
    send_response(client, "226 Transfer complete\r\n");
}

void process_command(SOCKET client, char* cmd) {
    printf("C: %s", cmd);
    
    if (strncmp(cmd, "USER", 4) == 0) 
        send_response(client, "230 User logged in\r\n");
    else if (strncmp(cmd, "PASV", 4) == 0)
        handle_pasv(client);
    else if (strncmp(cmd, "LIST", 4) == 0)
        handle_list(client);
    else if (strncmp(cmd, "RETR", 4) == 0)
        handle_retr(client, cmd + 5);  // 提取文件名
    else if (strncmp(cmd, "QUIT", 4) == 0)
        send_response(client, "221 Goodbye\r\n");
    else
        send_response(client, "500 Unknown command\r\n");
}

DWORD WINAPI client_thread(LPVOID lpParam) {
    SOCKET client = *(SOCKET*)lpParam;
    char buffer[BUFFER_SIZE];
    int bytes_received;

    send_response(client, "220 FTP Server Ready\r\n");

    while ((bytes_received = recv(client, buffer, BUFFER_SIZE, 0))) {
        if (bytes_received <= 0) break;
        buffer[bytes_received] = '\0';
        process_command(client, buffer);
    }

    closesocket(client);
    return 0;
}


void main()
{
    WSADATA wsa;
    SOCKET control_sock, client_sock;
    struct sockaddr_in server, client;
    int c;

    WSAStartup(MAKEWORD(2,2), &wsa);
    
    // 创建控制套接字
    control_sock = socket(AF_INET, SOCK_STREAM, 0);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(CONTROL_PORT);
    
    bind(control_sock, (struct sockaddr*)&server, sizeof(server));
    listen(control_sock, 3);
    
    printf("FTP Server listening on port %d...\n", CONTROL_PORT);

    // 主循环
    while ((client_sock = accept(control_sock, (struct sockaddr*)&client, &c))) {
        printf("Client connected\n");
        CreateThread(NULL, 0, client_thread, &client_sock, 0, NULL);
    }

    closesocket(control_sock);
    WSACleanup();

}